public class Matrix2 {
    private double[][] data;

    // 任务 1：构造函数初始化矩阵
    public Matrix2(double[][] data) {
        if (data == null) {
            throw new IllegalArgumentException("输入数据不能为空。");
        }

        int rowCount = data.length;
        int colCount = data[0].length;

        // 检查是否为不规则数组（行数不同长度）
        for (int i = 1; i < rowCount; i++) {
            if (data[i].length != colCount) {
                throw new IllegalArgumentException("所有行必须具有相同的列数。");
            }
        }

        // 深拷贝以确保不可变性
        this.data = new double[rowCount][colCount];
        for (int i = 0; i < rowCount; i++) {
            System.arraycopy(data[i], 0, this.data[i], 0, colCount);
        }
    }

    // 任务 2：获取矩阵数据的深拷贝
    public double[][] getData() {
        int rowCount = this.data.length;
        int colCount = this.data[0].length;
        double[][] copy = new double[rowCount][colCount];
        for (int i = 0; i < rowCount; i++) {
            System.arraycopy(this.data[i], 0, copy[i], 0, colCount);
        }
        return copy;
    }

    // 任务 3：矩阵加法
    public Matrix2 add(Matrix2 other) {
        int thisRows = this.data.length;
        int thisCols = this.data[0].length;
        int otherRows = other.data.length;
        int otherCols = other.data[0].length;

        // 检查矩阵是否具有相同的维度
        if (thisRows != otherRows || thisCols != otherCols) {
            throw new IllegalArgumentException("矩阵加法要求矩阵维度相同。");
        }

        double[][] result = new double[thisRows][thisCols];
        for (int i = 0; i < thisRows; i++) {
            for (int j = 0; j < thisCols; j++) {
                result[i][j] = this.data[i][j] + other.data[i][j];
            }
        }

        return new Matrix2(result);
    }

    // 任务 4：矩阵减法
    public Matrix2 subtract(Matrix2 other) {
        int thisRows = this.data.length;
        int thisCols = this.data[0].length;
        int otherRows = other.data.length;
        int otherCols = other.data[0].length;

        // 检查矩阵是否具有相同的维度
        if (thisRows != otherRows || thisCols != otherCols) {
            throw new IllegalArgumentException("矩阵减法要求矩阵维度相同。");
        }

        double[][] result = new double[thisRows][thisCols];
        for (int i = 0; i < thisRows; i++) {
            for (int j = 0; j < thisCols; j++) {
                result[i][j] = this.data[i][j] - other.data[i][j];
            }
        }

        return new Matrix2(result);
    }

    // 任务 5：矩阵乘法
    public Matrix2 multiply(Matrix2 other) {
        int thisRows = this.data.length;
        int thisCols = this.data[0].length;
        int otherRows = other.data.length;
        int otherCols = other.data[0].length;

        // 确保矩阵乘法是可能的
        if (thisCols != otherRows) {
            throw new IllegalArgumentException("第一个矩阵的列数必须等于第二个矩阵的行数。");
        }

        double[][] result = new double[thisRows][otherCols];
        for (int i = 0; i < thisRows; i++) {
            for (int j = 0; j < otherCols; j++) {
                for (int k = 0; k < thisCols; k++) {
                    result[i][j] += this.data[i][k] * other.data[k][j];
                }
            }
        }

        return new Matrix2(result);
    }

    // 任务 6：矩阵转置
    public Matrix2 transpose() {
        int rows = this.data.length;
        int cols = this.data[0].length;
        double[][] result = new double[cols][rows];

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                result[j][i] = this.data[i][j];
            }
        }

        return new Matrix2(result);
    }

    // 任务 7：矩阵行列式
    public double determinant() {
        int rows = this.data.length;
        int cols = this.data[0].length;

        // 只有方阵才有行列式
        if (rows != cols) {
            throw new IllegalArgumentException("行列式仅对方阵定义。");
        }

        if (rows == 2) {
            return this.data[0][0] * this.data[1][1] - this.data[0][1] * this.data[1][0];
        } else if (rows == 3) {
            return this.data[0][0] * (this.data[1][1] * this.data[2][2] - this.data[1][2] * this.data[2][1])
                    - this.data[0][1] * (this.data[1][0] * this.data[2][2] - this.data[1][2] * this.data[2][0])
                    + this.data[0][2] * (this.data[1][0] * this.data[2][1] - this.data[1][1] * this.data[2][0]);
        }

        return Double.NaN; // 对于更大的矩阵返回 NaN
    }
}
